#include "data.h"
#include "Extern_global_Variable.h"

template <typename T>
T TDataTable<T>::TDataTableEnumerator::GetCurrent()
{
	return FTable.UsedValues[FCurrentIndex];
};

template <typename T>
Boolean TDataTable<T>::TDataTableEnumerator::MoveNext()
{
	FCurrentIndex++;
	return FCurrentIndex < FTable.UsedValuesCount;
};

template <typename T>
procedure TDataTable<T>::TDataTableEnumerator::Reset()
{
	FCurrentIndex = -1;
};

template <typename T>
TDataTable<T>::TDataTableEnumerator::TDataTableEnumerator(TDataTable ATable)
{
	FTable = ATable;
	Reset();
};

template <typename T>
TDataTable<T> TDataTableManager<T>::CreateInstance()
{
	TDataTable<T> Result;
	Result.TDataTable::TDataTable();
	Result.Size = FTableSize;
	return Result;
};

template <typename T>
procedure TDataTableManager<T>::ClearInstance(TTable AInstance)
{
	AInstance.Clear();
};

template <typename T>
procedure TDataTableManager<T>::DestroyInstance(TTable AInstance)
{
	AInstance.~TTable();
};

template <typename T>
TDataTableManager<T>::TDataTableManager(Integer ATableSize)
{
	FTableSize = ATableSize;
};

template <typename T>
TDataTableManager<T>::~TDataTableManager()
{
	//inherited Destroy;
};

template <typename T>
procedure TDataTable<T>::SetValue(Integer AIndex, T &AValue)
{
		FSlots[AIndex].Value = AValue;

		if (!FSlots[AIndex].Used)
		{
			FSlots[AIndex].Used = TRUE;
			FUsedSlots.Add(AIndex);
		};
};

template <typename T>
Boolean TDataTable<T>::GetValue2(Integer AIndex, T &AValue)
{
	AValue = FSlots[AIndex].Value;
	return FSlots[AIndex].Used;
};

template <typename T>
T TDataTable<T>::GetValue(Integer AIndex)
{
	T Result;
	if (!GetValue2(AIndex, Result))
	{
		MessageBoxA(NULL,"Uninitialized slot accessed.","Error!",MB_OK | MB_ICONWARNING);
	};
	return Result;
};

template <typename T>
Integer TDataTable<T>::GetSize()
{
	return sizeof(FSlots)/sizeof(*FSlots);
};

template <typename T>
procedure TDataTable<T>::SetSize(Integer ASize)
{
	FSlots = new TDataSlot[ASize];
};

template <typename T>
T TDataTable<T>::GetUsedValue(Integer AIndex)
{
	return FSlots[FUsedSlots[AIndex]].Value;
};

template <typename T>
Integer TDataTable<T>::GetUsedValuesCount()
{
	return FUsedSlots.Count;
};

template <typename T>
TDataTable<T>::TDataTable()
{
	FSlots = NULL;
	FUsedSlots.Create();
};

template <typename T>
TDataTable<T>::~TDataTable()
{
	FUsedSlots.Destroy();
	//delete FUsedSlots;
	//inherited;
};

template <typename T>
procedure TDataTable<T>::Clear()
{
	Integer vvi;

	for (vvi = 0; vvi != FUsedSlots.vCount; vvi++)
	{
		FSlots[vvi].Used = FALSE;
	}

	FUsedSlots.vCount = 0;
};

template <typename T>
TDataTableEnumerator_2<T> TDataTable<T>::GetEnumerator()
{
	return TDataTableEnumerator(this);
};
